package main

import (
	"log"
	"reflect"
)

type studuent1 struct {
	Name string
	Age  int
}

type studuent2 struct {
	Name  string
	Age   int
	Age22 string
}

func reflects() {
	var olds = studuent2{
		Name:  "kso",
		Age:   230,
		Age22: "dd",
	}
	var new1 = studuent1{}
	err := structsToValues(&new1, olds)
	if err != nil {
		log.Fatal("structsToValues err info :", err)
	}
	log.Println(new1)
}

func structsToValues(newvalue interface{}, oldvalue interface{}) error {
	var oldv = reflect.ValueOf(oldvalue)
	var oldt = reflect.TypeOf(oldvalue)

	if oldt.Kind() == reflect.Ptr {
		oldv = oldv.Elem()
		oldt = oldt.Elem()
	}
	var newv = reflect.ValueOf(newvalue)
	var newt = reflect.TypeOf(newvalue)
	if newt.Kind() != reflect.Ptr {
		log.Fatalln("new is not reflect.Ptr ！ exit !")
	}
	newv = newv.Elem()
	newt = newt.Elem()
	if newt.Kind() != reflect.Struct || oldt.Kind() != reflect.Struct {
		log.Fatalln("newvalue or oldvalue is type not struct!")
	}
	var desttype = reflect.New(newt)
	for i := 0; i < newt.NumField(); i++ {
		destFieName := newt.Field(i)
		log.Println("destFieName:", destFieName.Name, "  . oldt fileName:", oldt.Field(i).Name)
		if sourceFilecd, ok := oldt.FieldByName(destFieName.Name); ok {
			if destFieName.Type != sourceFilecd.Type {
				continue
			}
			tovalue := oldv.FieldByName(destFieName.Name)
			log.Println("value : ", destFieName.Name, sourceFilecd.Name, tovalue)
			desttype.Elem().FieldByName(destFieName.Name).Set(tovalue)
		}
	}
	newv.Set(desttype.Elem())
	return nil
}
